package com.chuangke.login.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.beanutils.BeanMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.chuangke.common.db.page.CkPageQuery;
import com.chuangke.common.db.page.PageUtil;
import com.chuangke.common.http.HttpResult;
import com.chuangke.security.service.JwtTokenManager;
import com.chuangke.security.userdetails.JwtUserDetails;

import cn.hutool.core.util.StrUtil;

/**
 * 在线用户监控
 */
@RestController
@RequestMapping("/monitor/online")
public class SysUserOnlineController {

    @Autowired
    private JwtTokenManager jwtTokenManager;

    @SuppressWarnings({"unchecked", "rawtypes"})
    @PreAuthorize("hasAuthority('login:action')")
    @PostMapping("/list")
    public HttpResult list(@RequestBody Map<String, Object> pageQuery) {
        List<JwtUserDetails> userList = jwtTokenManager.listOnlineUser();
        List<JwtUserDetails> sortUserList = userList.stream().sorted(Comparator.comparing(JwtUserDetails::getLoginTime))
                .collect(Collectors.toList());

        String name = (String) pageQuery.get("name");

        sortUserList = sortUserList.stream().filter(userDetial -> ((StrUtil.isBlank(name) || (StrUtil.isNotBlank(name)
                && (userDetial.getUser().getName().contains(name) || userDetial.getUser().getNickName().contains(name)))
        ))).collect(Collectors.toList());

        IPage page = PageUtil.findPage(new CkPageQuery(pageQuery), sortUserList);
        List<Map<Object, Object>> records = new ArrayList<>();
        if (page.getRecords() != null) {
            page.getRecords().forEach(userDetail -> {
                Map<Object, Object> newRecord = new HashMap<>();

                newRecord.putAll(new BeanMap(userDetail));
                newRecord.putAll(new BeanMap(((JwtUserDetails) userDetail).getUser()));
                List<String> ignoreColumns = Arrays.asList("password", "salt", "userRoles", "authorities", "user");
                ignoreColumns.forEach(newRecord::remove);

                newRecord.put("expireTime", new Date(Long.parseLong(newRecord.get("expireTime").toString())));
                newRecord.put("loginTime", new Date(Long.parseLong(newRecord.get("loginTime").toString())));
                records.add(newRecord);
            });
        }
        page.setRecords(records);
        return HttpResult.ok(page);
    }

    /**
     * 强退用户
     */
    @PreAuthorize("hasAuthority('login:action')")
    @GetMapping("/forcelogout/{uuid}")
    public HttpResult forceLogout(@PathVariable String uuid) {
        jwtTokenManager.delLoginUser(uuid);
        return HttpResult.ok();
    }
}
